﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;

using ExchangeRateService.DataAccess;
using ExchangeRateService.Model;

namespace ExchangeRateService.ViewModel
{
	// <summary>
	/// Represents a container of CurrencyViewModel objects
	/// that has support for staying synchronized with the
	/// CurrencyRepository.  This class also provides information
	/// related to multiple selected currencies.
	/// </summary>
	public class RateSupplementViewModel : WorkspaceViewModel
	{
		#region Fields

		readonly CurrencyRepository _repository;
		
		ICollectionView _supplementView;
		
		String _nameFilter;

		#endregion // Fields

		#region Constructor

		public RateSupplementViewModel(CurrencyRepository repository)
		{
			if (repository == null)
				throw new ArgumentNullException("Currency Repository");

			base.DisplayName = Properties.StringResource.SHOW_RATES_SUPPLEMENT;

			_repository = repository;

			// Populate the supplement with list of CurrencyViewModel.
			this.FillSupplement();
		}

		void FillSupplement()
		{
			List<CurrencyViewModel> all =
				(from c in _repository.GetCurrencySupplement()
				 select new CurrencyViewModel(c, _repository)).ToList();

			foreach (CurrencyViewModel vm in all)
				vm.PropertyChanged += this.CurrencyViewModel_PropertyChanged;

			this.CurrencySupplement = new ObservableCollection<CurrencyViewModel>(all);
			//            this.CurrencySupplement.CollectionChanged += this.CurrencySupplement_CollectionChanged;
			
			_supplementView = CollectionViewSource.GetDefaultView(this.CurrencySupplement);
			_supplementView.Filter =
			            	o => String.IsNullOrEmpty(this.NameFilter) ? true : (o as CurrencyViewModel).Name.ToUpper().Contains(NameFilter.ToUpper());
		}

		#endregion // Constructor

		#region Public Interface
		
		/// <summary>
		/// Returns a collection of all the CurrencyViewModel objects.
		/// </summary>
		public ObservableCollection<CurrencyViewModel> CurrencySupplement { get; private set; }
		
		public String NameFilter
		{
			get { return _nameFilter; }
			set
			{
				if (_nameFilter != value)
				{
					_nameFilter = value;
					_supplementView.Refresh();
					OnPropertyChanged("NameFilter");
				}
			}
		}

		#endregion // Public Interface

		#region  Base Class Overrides

		protected override void OnDispose()
		{
			foreach (CurrencyViewModel custVM in this.CurrencySupplement)
				custVM.Dispose();

			this.CurrencySupplement.Clear();
			this.CurrencySupplement.CollectionChanged -= this.CurrencySupplement_CollectionChanged;
		}

		#endregion // Base Class Overrides

		#region Event Handling Methods

		void CurrencySupplement_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			if (e.NewItems != null && e.NewItems.Count != 0)
				foreach (CurrencyViewModel vm in e.NewItems)
					vm.PropertyChanged += this.CurrencyViewModel_PropertyChanged;

			if (e.OldItems != null && e.OldItems.Count != 0)
				foreach (CurrencyViewModel vm in e.OldItems)
					vm.PropertyChanged -= this.CurrencyViewModel_PropertyChanged;
		}

		void CurrencyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			string IsSelected = "IsSelected";

			// Make sure that the property name we're referencing is valid.
			// This is a debugging technique, and does not execute in a Release build.
			(sender as CurrencyViewModel).VerifyPropertyName(IsSelected);

			// When a customer is selected or unselected, we must let the
			// world know that the TotalSelectedSales property has changed,
			// so that it will be queried again for a new value.
			//            if (e.PropertyName == IsSelected)
			//                this.OnPropertyChanged("TotalSelectedSales");
		}

		#endregion // Event Handling Methods
	}
}
